package fileserver;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.util.Arrays;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

import client.Client;

import common.Constants;

public class FileServer {
	
	private static final int FS_PORT = 9997;

	//File to which byte streams from incoming udp packets are dumped
	private BufferedOutputStream fileHandle;
	
	private static Logger logger;
	
	private DatagramSocket socket;
    
        private String appendTarget;


	public FileServer(String file) throws IOException{
		
                this.appendTarget=file;

		logger = Logger.getLogger(FileServer.class);
		PropertyConfigurator.configure(Constants.LOG_CONFIG);		
		
		logger.info("Started file server. Listening for messages in port : "+FS_PORT);
		File f=new File(appendTarget);
		if(f.exists()){
			logger.info("File : "+appendTarget+" exists. Deleting it now.");
			f.delete();
		}
	

		this.socket =  new DatagramSocket(FS_PORT);
		
		while(true){
			// create an array of bytes to receive message
			byte[] dataToBeReceived = new byte[common.Constants.MAX_MSG_SIZE];

			// prepare a place for incoming packet
			DatagramPacket aPacket = new DatagramPacket(dataToBeReceived,
					dataToBeReceived.length);

			// receive a packet
			try {
				socket.receive(aPacket);
			} catch (IOException e) {
				e.printStackTrace();
			}
			
			append(aPacket);
		}
		
		
	}
	
	private void append(DatagramPacket aPacket) throws IOException{
		byte[] payload=aPacket.getData();
		String[] payloadParts=new String(payload).split(Constants.FIELD_SEPARATOR+"");
		int clientId=Integer.parseInt(payloadParts[0]);
		String data=payloadParts[2];
		append(data.getBytes(), clientId);
	}
	private void append(byte[] data, int clientId) throws IOException {
    		fileHandle = new BufferedOutputStream(new FileOutputStream(appendTarget, true));
		fileHandle.write(data);
		fileHandle.flush();
		fileHandle.close();
		logger.info("Wrote to file : "+appendTarget+" from : "+clientId+", Data : "+new String(data));
		
	}

	@Override
	public void finalize(){
		if(fileHandle!=null){
			try {
				fileHandle.close();
			} catch (IOException e) {				
				e.printStackTrace();
			}
		}
		
		if(socket!=null){
			socket.close();
		}
	}
	
	
	public static void main(String[] args) throws IOException{
		new FileServer(Constants.APPEND_TARGET);
	}
}